from QQLoginTool.QQtool import OAuthQQ
from django.contrib.auth import login
from django.shortcuts import render, redirect
from django import http
from django.views import View
from django.conf import settings
from meiduo_mall.utils.log import logger_out
from meiduo_mall.utils.response_code import RETCODE
from users.constants import USERNAME_COOKIE_EXPIRES
from .models import OAuthQQUser
from meiduo_mall.utils import meiduo_signature
from . import constants
from users.models import User
from django_redis import get_redis_connection
from meiduo_mall.utils import get_qq_infor
from carts.utils import merge_cart_cookie_to_redis


# 1.浏览器申请QQ登录，后台返回相应的授权地址
class OauthQQURLView(View):
    def get(self, request):
        # 设置获取下一个url的地址
        next_url = request.GET.get('next')
        # 需要设置client_id=None, client_secret=None,
        # redirect_uri=None, state=None
        oauthqq = OAuthQQ(settings.QQ_CLIENT_ID, settings.QQ_CLIENT_SECRET, settings.QQ_REDIRECT_URI, next_url)
        # 生成授权地址
        login_url = oauthqq.get_qq_url()
        # 响应
        return http.JsonResponse({
            'code': RETCODE.OK,
            'errmsg': "OK",
            'login_url': login_url,
        })


# 根据qq服务器的返回的数据提取openid
class OAuthQQOpenidView(View):
    def get(self, request):
        # 返回的地址：
        # http: // www.meiduo.site: 8000 / oauth_callback
        # ?code = 55236DDDCA443AF54B9CAD58DD9F819F
        # & state = % 2F
        code = request.GET.get('code')
        state = request.GET.get('state', '/')
        oauthqq = OAuthQQ(settings.QQ_CLIENT_ID, settings.QQ_CLIENT_SECRET, settings.QQ_REDIRECT_URI, state)
        # 根据code获取token
        token = oauthqq.get_access_token(code)
        # 根据token获取openid
        openid = oauthqq.get_open_id(token)
        # 获取用户信息
        info = get_qq_infor.get_user_infor(token, settings.QQ_CLIENT_ID, openid)
        # 打印获取的数据
        # 响应数据
        # 判断获取的id是否是初次获取:从数据库查询是否有该openid
        try:
            qquser = OAuthQQUser.objects.get(openid=openid)
        except Exception as e:  # 初次获取openid
            logger_out.warning(e)
            # 将openid加密后返回到前端去！
            json_str = meiduo_signature.dumps({"openid": openid}, constants.OPENID_EXPIRES)
            context = {'token': json_str, }
            return render(request, 'oauth_callback.html', context)
        else:  # 不是第一次获取openid
            user = qquser.user
            # 查询到授权对象，则状态保持，转到相关页面
            login(request, user)
            response = render(request, 'index.html')
            # 设置登录名
            response.set_cookie("username", user.username, max_age=USERNAME_COOKIE_EXPIRES)
            # 用户登录后将存储在cookies中的购物车商品保存在购物车中。
            response = merge_cart_cookie_to_redis(request, response)
            return response

    # 获取绑定表单的数据
    def post(self, request):
        # 接收：openid,mobile,password,sms_code
        access_token = request.POST.get("access_token")
        mobile = request.POST.get("mobile")
        pwd = request.POST.get("pwd")
        sms_code = request.POST.get('sms_code')

        state = request.GET.get('state', '/')
        # 验证：
        # 针对删除tb_oauth_qq中的用户，而没有删除user_tb的用户从而添加手机号相同的用户
        if User.objects.filter(username=mobile).count() > 0:
            return http.HttpResponseForbidden("该手机号已经存在！请换手机绑定！")

        # 验证手机号是否发送验证码ok
        # 验证手机号是否过期
        redis_cli = get_redis_connection("sms_code")
        sms_code_redis = redis_cli.get(mobile)
        if sms_code_redis is None:
            logger_out.warning("手机验证码已经过期！")
            return http.HttpResponseForbidden("手机验证码已经过期！")
        # 验证手机号是否输入错误！
        if sms_code_redis.decode("utf-8") != sms_code:
            logger_out.warning("手机验证码输入错误！")
            return http.HttpResponseForbidden("手机验证码输入错误！")

        # 1.对access_token的验证
        openid_json = meiduo_signature.loads(access_token, constants.OPENID_EXPIRES)
        if openid_json is None:
            return http.HttpResponseForbidden("授权无效！请重新QQ授权登录！")
        try:
            openid = openid_json.get('openid')
        except Exception as e:
            logger_out.warning(e)
            return http.HttpResponseForbidden("QQ授权已过期！请重新登录！")
        # 逻辑处理
        # 判断手机号是否已经使用
        try:
            user = User.objects.get(mobile=mobile)
        except:
            # 1.没使用，可以重新注册用户，然后登录
            user = User.objects.create_user(username=mobile, password=pwd, mobile=mobile)
        # 2.使用过，则判断密码，
        else:
            # 如果密码正确，绑定用户，如果错误，则提示，
            if not user.check_password(pwd):
                return http.HttpResponseForbidden("手机号已经使用过或密码错误")

        # 绑定qq用户对象
        qquser = OAuthQQUser.objects.create(user=user, openid=openid)
        # 登录,显示用户名并响应
        login(request, user)
        response = redirect(state)
        response.set_cookie('username', user.username)
        return response

